#pragma once

#include <glm/glm.hpp>
#include "engine/renderer/mesh/particle_system.h"
#include "engine/core/camera2d.h"
#include "engine/platform/shader.h"

namespace kanon
{
    struct ParticleVertex
    {
        glm::vec2 pos;
        glm::vec4 color;
    };

    struct ParticleBatch
    {
    private:
        friend class ParticleRenderer;
        uint32_t vao = -1;
        uint32_t vbo = -1;
        uint32_t ibo = -1;

        uint32_t max_vertices = 0;
        uint32_t max_indices = 0;
        uint32_t num_vertices = 0;
        uint32_t num_indices = 0;

        ParticleVertex* vertex_base;
        uint32_t* index_base;

    public:
        ParticleBatch(uint32_t max_particles);
        ~ParticleBatch();
        void Begin();
        void End();
        bool Submit(const Particle2D& p, const glm::vec4& color, const glm::vec2& base_position);
        bool Submit(const glm::vec2& pos, const glm::vec2& size, const glm::vec4& color);
    };

    class ParticleRenderer
    {
    protected:
        std::shared_ptr<ParticleBatch> batch;
        std::shared_ptr<Shader> shader;
        std::shared_ptr<Camera2d> camera;

    public:
        ParticleRenderer();
        void SetCamera(const std::shared_ptr<Camera2d>& cam);
        void Begin();
        void Render(const std::vector<Particle2D>& particles, 
            const glm::vec4& color, const glm::vec2& base_position);
        void End();

        void Flush();
    };
}
